/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.core.windows.nodes; import java.awt.Image; import java.awt.Component; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.beans.IntrospectionException; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectInputValidation; import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.*; import org.openide.util.datatransfer.PasteType; import org.openide.util.datatransfer.ExTransferable; import org.openide.TopManager; import org.openide.actions.*; import org.openide.cookies.OpenCookie; import org.openide.cookies.InstanceCookie; import org.openide.loaders.InstanceSupport; import org.openide.windows.Workspace; import org.openide.windows.Mode; import org.openide.windows.TopComponent; import org.openide.util.WeakListener; import org.openide.util.actions.SystemAction; import org.openide.nodes.*; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.netbeans.core.windows.WindowManagerImpl; import org.netbeans.core.windows.ModeImpl; import org.netbeans.core.windows.WorkspaceImpl; import org.netbeans.core.windows.toolbars.*; /** Node that displayes content of one workspace. * * @author Ales Novak, Jaroslav Tulach */ public final class WorkspaceContext extends AbstractNode implements InstanceCookie { /** Workspace for which we provide context */ private WorkspaceImpl workspace; /** element children */ private Elements children; /** default constructor * @param workspace is a workspace to provide context to */ public WorkspaceContext (Workspace workspace) { this (new Elements (workspace), workspace); } private WorkspaceContext (Elements ch, Workspace aworkspace) { super (ch); this.workspace = (WorkspaceImpl) aworkspace; this.children = ch; setName (workspace.getDisplayName()); setShortDescription (NbBundle.getBundle (WorkspaceContext.class).getString ("HINT_WorkspaceContext")); setIconBase ("/org/netbeans/core/resources/workspace"); // NOI18N // weak listener on changes in children and name workspace.addPropertyChangeListener( WeakListener.propertyChange(children, workspace) ); getCookieSet ().add (this); getCookieSet ().add (new OpenCookie () { public void open() { ((WindowManagerImpl) TopManager.getDefault().getWindowManager()). setCurrentWorkspace(WorkspaceContext.this.workspace); } }); } public HelpCtx getHelpCtx () { return new HelpCtx (WorkspaceContext.class); } /** * @param x is an Object to compare with * @return true iff this and x are equal */ public boolean equals (Object x) { if (x instanceof WorkspaceContext) return workspace == ((WorkspaceContext)x).workspace; return false; } /** * @return hashcode */ public int hashCode () { return workspace.hashCode(); } /** sets workspace name * @param x is a new name */ public void setName (String x) { super.setName(x); ((WorkspaceImpl)workspace).setDisplayName(x); } /** Yep, workspace could be renamed. */ public boolean canRename () { return true; } /** Creates properties for this data object */ protected Sheet createSheet () { Sheet s = Sheet.createDefault (); Sheet.Set ss = s.get (Sheet.PROPERTIES); ss.put (new Node.Property[] { new PropertySupport.Name (this, NbBundle.getBundle (WorkspaceContext.class).getString ("PROP_desk_name"), NbBundle.getBundle (WorkspaceContext.class).getString ("HINT_desk_name") ), new ToolbarConfigurationPropertyEditor (this) }); return s; } /** * @return toolbar configuration name */ public String getToolbarConfigName () { return workspace.getToolbarConfigName(); } /** * @param name of toolbar configuration for this workspace */ public void setToolbarConfigName (String name) { workspace.setToolbarConfigName (name); } /** * @return underlying workspace */ public Workspace getWorkspace () { return workspace; } /** Context menu that should be assigned to this Node. * @return the popup menu */ public SystemAction[] createActions () { return new SystemAction[] { SystemAction.get (OpenAction.class), null, SystemAction.get (CutAction.class), SystemAction.get (CopyAction.class), SystemAction.get (PasteAction.class), null, SystemAction.get (DeleteAction.class), SystemAction.get (RenameAction.class), null, SystemAction.get (ToolsAction.class), SystemAction.get (PropertiesAction.class) }; } /** Default action. */ public SystemAction getDefaultAction () { return SystemAction.get (OpenAction.class); } /** Removes the Node from its parent. * It is done via setting parent to null. It is responsibility of parent * to listen for that change. * * @exception NodeAccessException if something wrong occures */ public void destroy () throws IOException { workspace.remove(); } /** Can this node be removed? * @return <CODE>true</CODE> if can, <CODE>false</CODE> otherwise */ public boolean canDestroy () { return workspace != TopManager.getDefault().getWindowManager().getCurrentWorkspace(); } // cut & copy of workspaces ****************************************** /** @return true/false on workspace !=/== currentWorkspace */ public boolean canCut () { return workspace != TopManager.getDefault().getWindowManager().getCurrentWorkspace(); } /** @return true */ public boolean canCopy () { return true; } /** Checks for instances of workspace elements. */ protected void createPasteTypes (Transferable t, List s) { super.createPasteTypes (t, s); Mode e; e = element ((InstanceCookie)NodeTransfer.cookie (t, NodeTransfer.COPY, InstanceCookie.class)); if (e != null) { // copy flavor s.add (new TopFramePasteType (e, null)); return; } // node to be cut Node n = NodeTransfer.node (t, NodeTransfer.CLIPBOARD_CUT | NodeTransfer.DND_MOVE); if (n != null && n.canDestroy ()) { e = element ((InstanceCookie)n.getCookie (InstanceCookie.class)); s.add (new TopFramePasteType (e, n)); return; } } /** Takes workspace element from the instance cookie or not. * @param cookie instance cookie * @return the workspace element */ private Mode element (InstanceCookie cookie) { try { if (cookie != null && Mode.class.isAssignableFrom (cookie.instanceClass ())) { return (Mode)cookie.instanceCreate (); } } catch (Exception ex) { } return null; } /********* implementation of the instance cookie *****? /** The bean name for the instance. * @return the name */ public String instanceName () { return workspace.getName(); } /** The representation type that may be created as instances. */ public Class instanceClass () throws java.io.IOException, ClassNotFoundException { return workspace.getClass(); } /** Create new instance of represented workspace. */ public Object instanceCreate () throws java.io.IOException, ClassNotFoundException { return new WorkspaceImpl(workspace); } /** Children elements and listener on changes in the workspace. */ private static class Elements extends Children.Keys implements PropertyChangeListener { /** workspace we are attached to */ private Workspace workspace; public Elements (Workspace w) { // initialize setKeys (w.getModes()); workspace = w; } /** Creates new node for given element. * @param mode the mode on workspace * @return node for it */ protected Node[] createNodes (Object mode) { if (mode instanceof ModeImpl) return new Node[] { new ModeContext((ModeImpl)mode) }; // let bean node to take care if type unknnown try { return new Node[] { new BeanNode (mode) }; } catch (IntrospectionException ex) { return new Node[] { new AbstractNode (Children.LEAF) }; } } public void propertyChange (PropertyChangeEvent che) { if (che.getPropertyName().equals (Workspace.PROP_MODES)) { Mode[] modes = (Mode[])che.getNewValue(); if (modes == null) setKeys (workspace.getModes()); else setKeys(modes); } if (che.getPropertyName().equals (Workspace.PROP_NAME)) { String name = (String) che.getNewValue (); getNode ().setName (name); } } } /** Paste type for workspace elements */ private class TopFramePasteType extends PasteType { /** element to work with */ private Mode element; /** node to destroy or null */ private Node old; /** Constructs new TopFramePasteType for the specific type of operation paste. */ public TopFramePasteType (Mode element, Node old) { this.element = element; this.old = old; } /* @return Human presentable name of this paste type. */ public String getName () { return NbBundle.getBundle (WorkspaceContext.class).getString ("PASTE_TopFrame"); } /* @return help */ public HelpCtx getHelpCtx() { return new HelpCtx (TopFramePasteType.class); } /** Performs the paste action. * @return Transferable which should be inserted into the clipboard after * paste action. It can be null, which means that clipboard content * should stay the same. */ public Transferable paste() throws IOException { if (old != null) { old.destroy (); } // element.attachTo (workspace); Mode nevv = workspace.createMode( element.getName(), element.getDisplayName(), ((ModeImpl)element).getIconURL() ); TopComponent[] tcs = element.getTopComponents(); for (int i = 0; i < tcs.length; i++) { nevv.dockInto(tcs[i]); } return null; } } /* public ClipboardOperation childClipboardOperation (Object child) throws IllegalArgumentException { if (!(child instanceof TopFrame)) throw new IllegalArgumentException(); TopFrame frame = (TopFrame) child; Enumeration frames = workspace.getFrameList (); while (frames.hasMoreElements ()) { if (((TopFrame) frames.nextElement()) == frame) return new TopFrameClipboardOperation (workspace, frame); } throw new IllegalArgumentException(); }*/ /** Gets action that should be invoked in response to double click or press of * enter. * @return default action or null if the bean is not currently in state that would * allow execution of default action. */ // public org.openide.util.InvocableAction getDefaultAction() { // return new org.openide.util.InvocableAction () { /** Invokes the action. This should for example open new * window or create new thread for compilation. */ /* public void invoke (){ try { TopFrame frame = TopFrame.getRegistry().getSelectedFrame(); java.awt.Rectangle rec = frame.getBounds (); TopManager.getDefault().getWorkspacePool().setCurrentWorkspace (workspace); frame.setBounds (rec); frame.setVisible (true); } catch (java.beans.PropertyVetoException ex) { TopManager.getDefault().notifyException (ex); } } public String getName () { return workspace.getName (); } */ /** Help context where to find more about the action. * @return null */ /* public org.openide.util.HelpCtx getHelpCtx () { return null XXX; } }; } */ } /* * Log * 11 Gandalf 1.10 1/16/00 Jesse Glick Tool tips. * 10 Gandalf 1.9 1/12/00 Ian Formanek NOI18N * 9 Gandalf 1.8 12/17/99 David Simonek #3496 * 8 Gandalf 1.7 11/6/99 David Simonek new WeakListener * strategy followed... * 7 Gandalf 1.6 11/3/99 David Simonek completely rewritten * serialization of windowing system... * 6 Gandalf 1.5 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 5 Gandalf 1.4 7/29/99 David Simonek further ws serialization * changes * 4 Gandalf 1.3 7/28/99 David Simonek serialization of window * system...first draft :-) * 3 Gandalf 1.2 7/23/99 David Simonek workspaces in explorer * now nearly functional * 2 Gandalf 1.1 7/12/99 Jesse Glick Context help. * 1 Gandalf 1.0 7/11/99 David Simonek * $ * Beta Change History: * 0 Tuborg 0.12 --/--/98 Jan Jancura IndexedDiteContext removed * 0 Tuborg 0.13 --/--/98 Ales Novak set/get Name * 0 Tuborg 0.14 --/--/98 Ales Novak Serializable * 0 Tuborg 0.21 --/--/98 Jan Jancura propertySet * 0 Tuborg 0.25 --/--/98 Jaroslav Tulach Workspace.Element is now used * 0 Tuborg 0.27 --/--/98 Jan Formanek icons added * 0 Tuborg 0.28 --/--/98 Petr Hamernik rename cookie */